﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using InterLinq.Expressions;
using Sebarf.Core.Interfaces;
using Sebastof.Services.Interfaces;

#endregion

namespace Sebastof.Serialisation {
	/// <summary>
	/// Transfers an object 
	/// - that is not anonymous
	/// 
	/// </summary>
	[Serializable]
	public class ObjectTransportContainer {
		#region Public Properties

		/// <summary>
		/// Gets or sets the orignal value
		/// </summary>
		public object Value { get; set; }

		/// <summary>
		/// transfered metadata
		/// </summary>
		public IMetadataLocatorService TransferedMetadata { get; set; }

		public Dictionary<string, Dictionary<string, object>> TransferedData { get; set; }

		#endregion

		#region Public Methods

		/// <summary>
		/// Ctr
		/// </summary>
		/// <param name="value"></param>
		public ObjectTransportContainer(IServiceLocatorService ctx, Object value, IObjectMappingLocatorService om) {
			TransferedMetadata = new MetadataLocatorRegisterService();
			TransferedData = new Dictionary<string, Dictionary<string, object>>();
			if (value is ValueType || value is string || value == null) {
				//TransferedMetadata.Add(value, "UniqueIdentifier", objectIdentifierLocatorService.GetId(value));
				//omapperRegister.Add(objectIdentifierLocatorService.GetId(value), value);
				Value = value;
				return;
			}

			m_objectTreeHelperService = ctx.GetRegisteredService<IObjectTreeFlattenerService>();

			if (value is Expression) {
				value = (value as Expression).MakeSerializable();
			}
			Value = value;
			var objectIdentifierLocatorService = ctx.GetRegisteredService<IObjectIdentifierLocatorService>();
			var omapperRegister = ctx.GetRegisteredService<IObjectMappingRegisterService>();
			var dataHandlingStrategyService = ctx.GetRegisteredService<ISerializationDataHandlingStrategyService>();

			IList<IFlattenTreeObjectEntry> nestedobjs = m_objectTreeHelperService.GetFlattenTree(value);
			foreach (IFlattenTreeObjectEntry entry in nestedobjs) {
				object nestedo = entry.ObjectTreeEntry;
				TransferedMetadata.Add(nestedo, "UniqueIdentifier", objectIdentifierLocatorService.GetIdentityForObject(nestedo));
				omapperRegister.AddMapping(objectIdentifierLocatorService.GetIdentityForObject(nestedo), nestedo);

				if (nestedo is ISebastofApplicationObject) {
					var iObject = nestedo as ISebastofApplicationObject;
					if (!TransferedData.ContainsKey(iObject.Id)) {
						TransferedData.Add(iObject.Id, new Dictionary<string, object>());
					}
					foreach (var val in dataHandlingStrategyService.GetDataToTransferFromObject(nestedo)) {
						if (!TransferedData[iObject.Id].ContainsKey(val.Key)) {
							TransferedData[iObject.Id].Add(val.Key, val.Value);
						}
					}
				}
			}
		}

		#endregion

		#region Private Fields

		[NonSerialized]
		private IObjectTreeFlattenerService m_objectTreeHelperService;

		#endregion
	}
}